package com.gosling.cloudspace.service;

import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.MyConfig;
import com.gosling.cloudspace.common.constants.CommonCodeEnum;
import com.gosling.cloudspace.common.constants.CommonConstants;
import com.gosling.cloudspace.common.entity.BaseResult;
import com.gosling.cloudspace.common.entity.dtos.OrderInfoDto;
import com.gosling.cloudspace.common.entity.pojo.OrderInfoPO;
import com.gosling.cloudspace.common.entity.pojo.UserInfoPO;
import com.gosling.cloudspace.common.exception.CommonException;
import com.gosling.cloudspace.common.service.OrderInfoService;
import com.gosling.cloudspace.common.service.WxPayService;
import com.gosling.cloudspace.tools.IdNoUtil;
import com.gosling.cloudspace.tools.RegexTool;
import com.gosling.cloudspace.tools.XmlTool;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 微信支付的实现类
 *
 * @ClassName WxPayServiceImpl
 * @Author @OSC_lihonglin
 * @Date 2021/5/12 23:24
 * @Version 1.0
 */
@Service
public class WxPayServiceImpl implements WxPayService {
    protected static final Logger logger = LoggerFactory.getLogger(WxPayServiceImpl.class);

    @Autowired
    private OrderInfoService orderInfoService;

    @Override
    public BaseResult nativePay(OrderInfoDto orderInfoDto) {
        try {
            String money = orderInfoDto.getPayMoney();
            String orderName = orderInfoDto.getOrderName();
            if (StringUtils.isEmpty(orderName)) {
                logger.error("请输入商品名称！");
                throw new CommonException("请输入商品名称！");
            }
            //金额只能支持两位数的小数
            if (StringUtils.isEmpty(money) || !RegexTool.isMoney(money)) {
                logger.error("输入金额不合法！");
                throw new CommonException("输入金额不合法！");
            }
            UserInfoPO user = new UserInfoPO();
            if (Objects.isNull(user)) {
                logger.error("获取当前用户异常！");
                throw new CommonException("获取当前用户异常！");
            }
            //使用雪花算法生成订单号
            String orderId = IdNoUtil.nextId("T");
            BigDecimal payMoney = new BigDecimal(money);
            String paymentAmount = payMoney.toString();
            Map<String, String> map = new HashMap<>(8);
            //商品描述
            map.put("body", orderName);
            //微信订单号
            map.put("out_trade_no", orderId);
            //支付金额
            map.put("total_fee", paymentAmount);
            //用户终端IP
            map.put("spbill_create_ip", CommonConstants.LOCALHOST_IP);
            //回调地址,先随便填一个
            map.put("notify_url", "http://www.gosling/wxpay/notify");
            //交易类型
            map.put("trade_type", "NATIVE");
            //先在自己这边创建订单
            OrderInfoPO orderInfoPO = new OrderInfoPO();
            orderInfoPO.setUserId(user.getUserId());
            orderInfoPO.setOrderNo(orderId);
            orderInfoPO.setPaymentAmount(payMoney);
            orderInfoPO.setCreateTime(LocalDateTime.now());
            orderInfoPO.setUpdateTime(LocalDateTime.now());
            orderInfoPO.setOrderName(orderName);
            orderInfoPO.setType("0");
            orderInfoPO.setTradeType("NATIVE");
            orderInfoPO.setReturnMsg(CommonConstants.WXPAY_MSG_DEFAULT);
            orderInfoPO.setReturnCode(CommonConstants.WXPAY_CODE_DEFAULT);
            orderInfoPO.setRequestJson(JSON.toJSONString(orderInfoPO));
            orderInfoService.save(orderInfoPO);
            logger.info("订单创建成功:{}", JSON.toJSONString(orderInfoPO));
            //自己这边创建订单后然后 调用统一下单
//            WXPay wxPay = new WXPay(new MyConfig());
//            Map<String, String> mapResult = wxPay.unifiedOrder(map);
            Map<String, String> mapResult = map;
            if (Objects.isNull(mapResult)) {
                logger.error("微信支付异常！");
                throw new CommonException(CommonCodeEnum.WX_PAY_ERROR);
            }
            orderInfoPO.setResponseJson(JSON.toJSONString(mapResult));
            //微信响应参数后，更新响应参数，方便后期维护
            orderInfoService.updateById(orderInfoPO);
            String codeUrl = mapResult.get("code_url");
            logger.error("code_url:{}", codeUrl);
            return BaseResult.success(CommonCodeEnum.SUCCESS, codeUrl);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            throw new CommonException(CommonCodeEnum.SERVER_ERROR);
        }
    }

    /***
     * 订单查询
     * @param orderId
     * @return
     */
    @Override
    public BaseResult orderquery(String orderId) {
        try {
            MyConfig config = new MyConfig();
//            WXPay wx = new WXPay(config);
            Map<String, String> data = new HashMap<>(1);
            data.put("out_trade_no", orderId);
//            return BaseResult.success(CommonCodeEnum.SUCCESS, wx.orderQuery(data));
            return BaseResult.success(CommonCodeEnum.SUCCESS, "");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            return BaseResult.failed(CommonCodeEnum.SERVER_ERROR);
        }
    }

    /***
     * 订单查询
     * @param request
     * @param response
     * @return
     */
    @Override
    public void orderNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            String xml = XmlTool.convertToString(request.getInputStream());
//            Map<String, String> map = WXPayUtil.xmlToMap(xml);
            Map<String, String> map = new HashMap<>();
            //出款订单号
            String outTradeNo = map.get("out_trade_no");
            //响应结果码
            String resultCode = map.get("result_code");
            //错误响应码
            String errCodeDes = map.get("err_code_des");
            errCodeDes = StringUtils.isBlank(errCodeDes) ? "系统错误！" : errCodeDes;
            if (!map.isEmpty() && CommonConstants.WXPAY_MSG_SUCCESS.equals(resultCode) && StringUtils.isNotBlank(outTradeNo)) {
                Map<String, String> data = new HashMap<>(1);
                data.put("out_trade_no", outTradeNo);
//                WXPay wxPay = new WXPay(new MyConfig());
//                Map orderQueryData = wxPay.orderQuery(data);
                Map orderQueryData = new HashMap();
                if (Objects.nonNull(orderQueryData) && orderQueryData.isEmpty()) {
                    if (CommonConstants.WXPAY_MSG_SUCCESS.equals(resultCode)) {
                        OrderInfoPO orderInfoPO = orderInfoService.findByOrderNo(outTradeNo);
                        orderInfoPO.setReturnMsg(CommonConstants.WXPAY_MSG_SUCCESS);
                        orderInfoPO.setReturnCode(resultCode);
                        orderInfoService.updateById(orderInfoPO);
                    }
                }
            } else {
                logger.error("微信支付回调时出错:{}", errCodeDes);
            }
            //返回结果
            response.setContentType("text/xml");
            StringBuilder data = new StringBuilder();
            data.append("<xml> ");
            data.append(" ");
            data.append("<return_code><![CDATA[SUCCESS]]></return_code>");
            data.append(" ");
            data.append("<return_msg><![CDATA[OK]]></return_msg>");
            data.append(" ");
            data.append("</xml>");
            response.getWriter().write(data.toString());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("微信支付回调时出错:{}", e.getMessage(), e);
        }
    }
}
